package org.NooLab.itexx.app.controller;



import java.util.ArrayList;

import org.NooLab.itexx.ITexxWindowCommons;
import org.NooLab.itexx.ITexxWindowIntf;
import org.NooLab.itexx.app.gui.StackedPanel;
import org.NooLab.itexx.app.gui.StackedPanelProducer;
import org.NooLab.itexx.app.gui.definition.ITexxWindowGuiIntf;
import org.NooLab.itexx.app.gui.handlers.ResultPanelSelectionIndicator;
import org.NooLab.itexx.browser.BrowserHostList;
import org.NooLab.itexx.browser.DjBrowserHostIntf;
import org.NooLab.itexx.browser.DjBrowserListener;
import org.NooLab.itexx.retrieval.RequestDispatcher;
import org.NooLab.itexx.retrieval.RequestPreProcessing;
import org.NooLab.itexx.retrieval.RequestPreProcessingIntf;
import org.NooLab.itexx.retrieval.RetrievalEngine;
import org.NooLab.itexx.retrieval.SearchRequestHandler;
import org.NooLab.itexx.stuctures.GuiPersistenceData;
import org.NooLab.itexx.stuctures.RequestFocusContext;
import org.NooLab.utilities.datatypes.IndexDistance;
import org.NooLab.utilities.datatypes.IndexedDistances;
import org.NooLab.utilities.files.BareBonesBrowserLaunch;
import org.NooLab.utilities.logging.PrintLog;





public class ItexxModelController {

	/*
	    preferences
		adaptivesize=1|||
		
	 */
	
	ITexxWindowIntf texxWindowApp;
	ITexxWindowGuiIntf windowGui;
	ITexxWindowCommons appCommons;
	
	private StackedPanelProducer panelProducer ;
	
	SearchRequestHandler searchRequest ;// = new SearchRequestHandler();
	RetrievalEngine retrievalEngine ;

	private RequestFocusContext requestFocusContext;
	ResultPanelSelectionIndicator selectionIndicator;
	
	private boolean fullRequest ;

	private boolean fileContext;
	private RequestPreProcessingIntf requestPreProcessing;
	private int responsiveness= -1;
	private boolean userBreak=false;
	private PrintLog out;
	private int lastClickedPhysicalPanel=-1;
	
	ArrayList<String> confirmedLanguages = new ArrayList<String>(); 
	// this maintains a list of mappings from physical panels (primary index) to logical items (secondary index)
	// while the value contains the score value for easy sorting
	// the logical (secondary) index refers to the global results list
	IndexedDistances panelMap = new IndexedDistances ();
	private IndexedDistances globalUrlList;
	
	// ========================================================================
	public ItexxModelController(ITexxWindowIntf app) {
	
		texxWindowApp = app;
		windowGui = texxWindowApp.getWindowGui();
		// app.getAppCommons().setModelController(this);
	
		selectionIndicator = new ResultPanelSelectionIndicator( windowGui ) ;
		
		requestFocusContext = new RequestFocusContext(app);
		
		requestPreProcessing = new RequestPreProcessing( app ) ;
		
		globalUrlList = new IndexedDistances(); 
	}
	// ========================================================================


	// ========================================================================
	
	
	/**
	 * called e.g. in  DjBrowserHost::update(), 
	 * or upon transmission of data via the clipboard
	 * in main app::setClipboardString
	 * 
	 * this here is just a facade
	 * @return 
	 */
	public GuiPersistenceData updateFocusDataFromGui() {
		
		updateAppCommons();
		
		GuiPersistenceData guiData;
		guiData = requestFocusContext.updateFocusDataFromGui();
		
		// it is now also in the GuiPersistence object !!! 
		// GuiPersistenceData guiData = requestFocusContext.getGuiPersistence().getGuiData();
		return guiData;
	}



	private void updateAppCommons() {
		// 
		if (appCommons==null){
			appCommons = texxWindowApp.getAppCommons();
		}
		out = appCommons.out ;
	}

	public void close(){
		
		
	}
	
	public void tmp(){
		SessionManager smgr ;
		IndexDistance globurlitem ;
		String urlStr ;
		// save to tmp file		getGlobalUrlList
		
		smgr = appCommons.getSessionManager() ;
		
		for (int i=0;i<globalUrlList.size();i++){
			
			globurlitem = globalUrlList.getItem(i);
			urlStr = globurlitem.getGuidStr() ;
			
			out.print(2, ""+globurlitem.getIndex()+" , "+globurlitem.getIndex2()+", "+ urlStr) ;
		}//->
		
	}
	
	public boolean someProcessesAreAlive() {
		// 
		boolean rB = false;
		
		boolean[] procIsRunning = new boolean[3];
		for (int i=0;i<procIsRunning.length;i++){ procIsRunning[i]=false ;}
		
		BrowserHostList hostlist ;
		DjBrowserHostIntf browserHost ;
		DjBrowserListener browserListener ;
		PageLoader pageLoader ;
		RequestDispatcher rqDispatcher ;
		
		out.delay(2000);
		
		rqDispatcher = appCommons.getRequestDispatcher();
		
		
		pageLoader = appCommons.getPageLoader();
		if (procIsRunning[0])procIsRunning[0] = pageLoader.resultsDigesterIsRunning;
		
		hostlist = appCommons.getHostList();
		browserHost = hostlist.get(0);
		browserListener = browserHost.getListener();
		if (procIsRunning[1])procIsRunning[1] = (browserListener.isApproximatelyCompleted()==false);
		
		if (procIsRunning[2])procIsRunning[2] = searchRequest.isDispatcherIsRunning()  ;
		
		for (int i=0;i<procIsRunning.length;i++){ 
			if (procIsRunning[i]){
				rB=true;
				break;
			}
		}
		return rB;
	}


	public void showSearchWindow(int i) {
		// search..., we offer the opportunity for www search as well, 
		// through means of 2 different buttons 
		
	}

	
	public IndexedDistances getPanelMap() {
		return panelMap;
	}


	// popuphandling 
	public void openPanelSource(int panelIndex) {
		// 
		// in the future, similar things will be slightly up-weighted !
		// registerWeightChange( url, query)
		
		if (appCommons==null){
			appCommons = texxWindowApp.getAppCommons();
			out = appCommons.out ;
		}
		
		SessionManager smgr = appCommons.getSessionManager();
		
		if (smgr==null){
			// should never happen... anyway: show a message
			return;
		}
		
		// we have to ask the panel map in the session manager
		
		String url = smgr.getSourceForPhysicalPanel(panelIndex);
		
		if (url.length()==0){
			out.printErr(1, "Unable to find url (was empty).");
			return;
		}
		if (url.contentEquals("-")){
			// error
			out.printErr(1, "Url reference not found.");
			return;
		}
		try{
			BareBonesBrowserLaunch.openURL( url );
		}catch(Exception e){
			out.printErr(1, "Web document not found.");
			// TODO: dialog message
		}
	}


	public void storePanelSource(int itemIndex) {
		// 
		// this choice should be remembered with respect to URL and to content !!
		// in the future, similar things will be significantly up-weighted !
		
	}

	public void excludeDomainOfPanelSource(int itemIndex) {
		// it is a remote source, then put it to the ist of excluded domains
		// we need then also a tool to edit this list
		
	}


	public void removePanel(int itemIndex, int inclWeightModifiers) {
		// this choice should be remembered with respect to URL and to content !!
		// in the future, similar things will be down-weighted !
		updateAppCommons();
		out.print(2, "ItexxModelController is going to remove content from panel <"+itemIndex+">...");
		clearPanelList(1);
	}


	public void clearPanelList(int remainingItems) {
		
		// if remainingItems=0 then the "nothing found" message will 
		// appear on the first one
		// note that there are ALWAYS at least 5 physical panels, even if they are empty
		
		updateAppCommons();
		out.print(2, "ItexxModelController is going to clear the result list...");
		
		panelMap.clear();
		
		if (panelProducer==null){
			panelProducer = appCommons.getPanelProducer() ; 
		}
		panelProducer.clearPanels(1);
		
		// the nothing found message
		appCommons.getStackedPanelProducer().getPanels().getItem(0).setText("  nothing found or re-loaded so far ..." ) ;
		
		// appCommons
		int h = (int)(1.2 * appCommons.getAppProperties().getIniPreferences().getPanelsDefaultHeight());
		if (windowGui.isSimpleWindow()){
			h = h + windowGui.getMainStatusBar().getHeight() + 50 + 20;
			windowGui.setActualFrameHeight( h ) ;
			
		}else{
			 
		}
		
		
	}
	// popuphandling 

	public SearchRequestHandler getSearchRequest() {
		
		if (searchRequest==null){
			
			searchRequest = new SearchRequestHandler(texxWindowApp);
			
		}else{
			if (searchRequest.isDispatcherIsRunning()==false){
				// searchRequest.startDispatcher();
			}	
		}
		
		return searchRequest;
	}


	public void setRequestFocusContext(RequestFocusContext requestFocusContext) {
		this.requestFocusContext = requestFocusContext;
	}


	public RequestFocusContext getRequestFocusContext() {
		return requestFocusContext;
	}


	public RequestPreProcessingIntf getRequestPreProcessing() {
		return requestPreProcessing;
	}


	public void setRequestPreProcessing(RequestPreProcessingIntf requestPreProcessing) {
		this.requestPreProcessing = requestPreProcessing;
	}


	public void setFileContext(boolean fileContext) {
		this.fileContext = fileContext;
	}


	public boolean isFileContext() {
		return fileContext;
	}


	public void setFullRequest(boolean fullRequest) {
		this.fullRequest = fullRequest;
	}


	public boolean isFullRequest() {
		return fullRequest;
	}


	public ITexxWindowIntf getTexxWindowApp() {
		return texxWindowApp;
	}


	public void setResponsiveness(int flag) {
		// 
		responsiveness = flag;
	}


	public int getResponsiveness() {
		return responsiveness;
	}


	public void setUserBreak(boolean flag) {
		// 
		userBreak = flag;
	}


	public boolean isUserBreak() {
		return userBreak;
	}


	public void setLastClickedPhysicalPanel(int panelIndex) {
		// 
		lastClickedPhysicalPanel = panelIndex;
	}
	public int getLastClickedPhysicalPanel() {
		// 
		return lastClickedPhysicalPanel;
	}


	public boolean urlIsExcluded(String urlStr) {
		// 
		boolean rB=false;
		
		ArrayList<String> excludedDomains = appCommons.getAppProperties().getIniPreferences().getExcludedDomains() ;
		
		
		if ((excludedDomains!=null) && (excludedDomains.size()>0)){
			String ds = appCommons.strgutil.getDomainFromUrl(urlStr);
			boolean hb ;
			hb = excludedDomains.indexOf(ds)>=0;
			if (hb==false){
				ds = ds.replace("www.", "");
				hb = excludedDomains.indexOf(ds)>=0;
			}
			if (hb){
				rB=true;
			}
		}
		return rB;
	}


	public void setCurrentRawRequest(String indata) {
		// TODO Auto-generated method stub
		
	}


	public boolean isCurrentRawRequestRepeated(String indata) {
		// TODO Auto-generated method stub
		return false;
	}


	public IndexedDistances getGlobalUrlList() {
		// 
		return globalUrlList;
	}


	public void addConfirmedLanguage(String lang) {
		// 
		if (confirmedLanguages.contains(lang)==false){
			confirmedLanguages.add(lang);
		}
		
		updateAppCommons();
		
		int nx = appCommons.getAppProperties().getIniPreferences().getOpenNlpLanguages().size();
		
		if (nx>confirmedLanguages.size()){
			appCommons.getWindowGui().setStatusLabelText("please wait, language(s) have to be initialized... ");
		}else{
			appCommons.getWindowGui().setStatusLabelText("All nlp modules have been initialized.",4000); 
		}
	}


	
	
	
}
